import { createAction, PayloadAction } from '@reduxjs/toolkit';
import { Epic, ofType } from 'redux-observable';
import { from, of } from 'rxjs';
import { switchMap, takeUntil, catchError, mergeMap } from 'rxjs/operators';

import { ROUTES, SOURCE } from 'utils/constant';
import getSourceApi from 'src/api/source';
import { actions as otherActions } from 'src/redux/other';
import { actions as searchActions } from './slices';
import { push } from 'connected-react-router';

const loadSearchDetails = (address: string) => getSourceApi.getClassDetail(address);

// ********************************** redux actions ****************************

const loadSearchDetailsEA = createAction<{ key: string; address: string }>('loadSearchDetails');
const loadAllSearchSourceEA = createAction<string>('loadAllSearchSource');
const clearSearchDetailsEA = createAction('clearSearchDetails');
const gotoSearchEA = createAction('gotoSearch');
const gotoHomeEA = createAction('gotoHome');
const gotoPlayEA = createAction('gotoPlay');

// ********************************** redux-observable Epic ********************:

const loadSearchDetailsEpic: Epic = (actions$) =>
  actions$.pipe(
    ofType(loadSearchDetailsEA.type),
    mergeMap(({ payload }: PayloadAction<{ key: string; address: string }>) =>
      from(loadSearchDetails(payload.address)).pipe(
        takeUntil(actions$.pipe(ofType(otherActions.setCancelAction.type))),
        mergeMap((result) => of(searchActions.addSearch({ key: payload.key, value: result }))),
      ),
    ),
    catchError(() => of(otherActions.setLoading(false))),
  );

const loadAllSearchSourceEpic: Epic = (actions$) =>
  actions$.pipe(
    ofType(loadAllSearchSourceEA.type),
    switchMap(({ payload }: PayloadAction<string>) =>
      from(SOURCE.entries()).pipe(
        mergeMap((source) =>
          // from(loadClassDetails(source[1] + payload)).pipe(
          //   switchMap((result) => of(searchActions.addSearch({ key: source[0], value: result }))),
          // ),
          of(loadSearchDetailsEA({ key: source[0], address: source[1] + payload })),
        ),
      ),
    ),
  );

const clearSearchDetailsEpic: Epic = (actions$) =>
  actions$.pipe(
    ofType(clearSearchDetailsEA.type),
    switchMap(() => of(searchActions.clearVideosAndAttr())),
  );

const gotoSearchEpic: Epic = (actions$) =>
  actions$.pipe(
    ofType(gotoSearchEA.type),
    switchMap(() => of(push(ROUTES.SEARCH))),
  );

const gotoHomeEpic: Epic = (actions$) =>
  actions$.pipe(
    ofType(gotoHomeEA.type),
    switchMap(() => of(push(ROUTES.HOME))),
  );

const gotoPlayEpic: Epic = (actions$) =>
  actions$.pipe(
    ofType(gotoPlayEA.type),
    switchMap(() => of(push(ROUTES.PLAY))),
  );

export const epics = [
  loadSearchDetailsEpic,
  clearSearchDetailsEpic,
  loadAllSearchSourceEpic,
  gotoSearchEpic,
  gotoHomeEpic,
  gotoPlayEpic,
];

export const epicActions = {
  loadSearchDetails: loadSearchDetailsEA,
  clearSearchDetails: clearSearchDetailsEA,
  loadAllSearchSource: loadAllSearchSourceEA,
  gotoSearch: gotoSearchEA,
  gotoHome: gotoHomeEA,
  gotoPlay: gotoPlayEA,
};
